package com.link.base.base.appinfo.service;

import com.link.base.base.appinfo.dao.mybatis.mapper.AppVersionMapper;
import com.link.base.base.appinfo.model.AppVersion;
import com.link.core.basic.dao.mapper.BasicMapper;
import com.link.core.basic.service.BasicServiceException;
import com.link.core.basic.service.BasicServiceImpl;
import com.link.core.cllog.LCLogger;
import com.link.core.util.*;
import com.link.core.util.redisclient.LinkRedisClient;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;


import javax.annotation.Resource;
import java.io.*;
import java.util.Date;

/**
 * 版本管理服务
 *
 * @author ouyangzhenqiang
 * @date 2018/10/16
 */
@Service
public class AppVersionServiceImpl extends BasicServiceImpl<AppVersion> implements AppVersionService {

    @Resource
    private AppVersionMapper appVersionMapper;

    @Override
    public BasicMapper<AppVersion> getBasicMapper() {
        return appVersionMapper;
    }

    @Override
    @Transactional(rollbackFor = BasicServiceException.class)
    public void publishAppVersion(AppVersion record) throws Exception {
        LCLogger.info().withMessageKey("publishAppVersion(AppVersion record)").withMessage("版本发布＝> bundle id：" + record.getAppType()).flush();
        if (StringUtils.isBlank(record.getId() + "")) {
            throw new BasicServiceException("请传入版本记录Id！");
        }
        AppVersion appVersion = appVersionMapper.queryById(record);
        if (appVersion == null) {
            throw new BasicServiceException("未匹配到版本记录，请检查传入的Id！");
        }
        String status = appVersion.getReleaseStatus();
        String mobile_web_file_key = "mobile_web_file_path";
        String filePath = PropertyUtil.getProperty(mobile_web_file_key, AppConstants.ADMIN_CORP_ID);
        if ("WAIT PUBLISH".equals(status)) {
            // 版本预发布的plist模版
            String plistTempFilePathPlan = filePath + "/download/plist/" + appVersion.getAppType() + "/app.temp.plan.plist";
            // 版本预发布的plist
            String plistFilePathPlan = filePath + "/download/plist/" + appVersion.getAppType() + "/app.plan.plist";
            /* 1、基于Id将记录状态修改为预发布 */
            appVersionMapper.setPlanPublishUpdate(appVersion);
            /* 2、设置plist中ipa的值 */
            setPlistIpaUrl(plistTempFilePathPlan, plistFilePathPlan, appVersion.getIpaUrl());
            /* 3、将需要发布的版本信息写入Redis */
            setRedisInfo(appVersion, "plan");
        } else if ("PLAN PUBLISH".equals(status)) {
            // 版本发布的plist模版
            String plistTempFilePath = filePath + "/download/plist/" + appVersion.getAppType() + "/app.temp.plist";
            // 版本发布的plist
            String plistFilePath = filePath + "/download/plist/" + appVersion.getAppType() + "/app.plist";
            /* 1、基于appType，针对同类应用且发布状态为 “已发布/预发布” 的记录，将其发布状态设置为已过期 */
            appVersionMapper.batchSetExpiredUpdate(appVersion);
            /* 2、基于rowId，修改记录发的发布状态为已发布 */
            appVersionMapper.setPublishedUpdate(appVersion);
            /* 3、设置plist中ipa的值 */
            setPlistIpaUrl(plistTempFilePath, plistFilePath, appVersion.getIpaUrl());
            /* 4、将需要发布的版本信息写入Redis */
            setRedisInfo(record, "release");
        } else {
            throw new BasicServiceException("请对待发布/预发布状态的版本记录进行发布操作！");
        }
    }

    /**
     * 存储版本信息至Redis
     *
     * @author ouyangzhenqiang
     * @date 2018/10/16
     * @param record 版本记录
     * @param releaseStatus 发布类型
     */
    private void setRedisInfo(AppVersion record, String releaseStatus) throws Exception {
        LinkRedisClient j = null;
        try {
            LCLogger.info().withMessageKey("setRedisInfo(AppVersion record)").withMessage("开始存储版本信息至Redis...").flush();
            String redisKey = "app_info_" + record.getAppType();
            String version =  "?v=" + record.getAppLV() + "." + record.getAppMV();
            j = RedisUtil.getJedis();
            if ("release".equals(releaseStatus)) {
                // 大版本号
                j.hset(redisKey, "appLV", StringUtils.null2EmptyString(record.getAppLV()));
                // 小版本号
                j.hset(redisKey, "appMV", StringUtils.null2EmptyString(record.getAppMV()));
                // 版本更新提示
                j.hset(redisKey, "updateTips", StringUtils.null2EmptyString(record.getUpdateTips()));
                // iOS更新包大小
                j.hset(redisKey, "ipaSize", StringUtils.null2EmptyString(record.getIpaSize()));
                // 安卓更新包大小
                j.hset(redisKey, "apkSize", StringUtils.null2EmptyString(record.getApkSize()));
                // 版本更新日期
                j.hset(redisKey, "updateDt", DateUtil.dateToStr(new Date(),null));
                // apk下载地址
                j.hset(redisKey, "apkDownloadUrl", StringUtils.null2EmptyString(record.getApkUrl()) + version);
                // ipa下载地址
                j.hset(redisKey, "ipaDownloadUrl", StringUtils.null2EmptyString(record.getIpaUrl()) + version);
            } else if ("plan".equals(releaseStatus)) {
                // 大版本号
                j.hset(redisKey, "appLVPlan", StringUtils.null2EmptyString(record.getAppLV()));
                // 小版本号
                j.hset(redisKey, "appMVPlan", StringUtils.null2EmptyString(record.getAppMV()));
                // 版本更新提示
                j.hset(redisKey, "updateTipsPlan", StringUtils.null2EmptyString(record.getUpdateTips()));
                // iOS更新包大小
                j.hset(redisKey, "ipaSizePlan", StringUtils.null2EmptyString(record.getIpaSize()));
                // 安卓更新包大小
                j.hset(redisKey, "apkSizePlan", StringUtils.null2EmptyString(record.getApkSize()));
                // 版本更新日期
                j.hset(redisKey, "updateDtPlan", DateUtil.dateToStr(new Date(),null));
                // apk下载地址
                j.hset(redisKey, "apkDownloadUrlPlan", StringUtils.null2EmptyString(record.getApkUrl()) + version);
                // ipa下载地址
                j.hset(redisKey, "ipaDownloadUrlPlan", StringUtils.null2EmptyString(record.getIpaUrl()) + version);
            }
        } finally {
            RedisUtil.returnResource(j);
        }
    }

    /**
     * 设置plist模版中的ipaUrl
     *
     * @author ouyangzhenqiang
     * @date 2019/08/22 17:31
     * @param tempFilePath 模版文件路径
     * @param filePath 生成文件路径
     * @param ipaUrl ipa地址
     */
    private void setPlistIpaUrl(String tempFilePath, String filePath, String ipaUrl) throws Exception {
        File plistTempFile = new File(tempFilePath);
        String encoding = "UTF-8";
        if (plistTempFile != null && plistTempFile.exists()) {
            // 考虑到编码格式
            try (InputStreamReader read = new InputStreamReader(new FileInputStream(tempFilePath), encoding)) {
                try (BufferedReader bufferedReader = new BufferedReader(read)) {
                    String plist = "";
                    String txt = "";
                    while ((txt = bufferedReader.readLine()) != null) {
                        plist = plist + txt;
                    }
                    read.close();
                    plist = plist.replace("###ipaUrl###", ipaUrl);
                    try (FileOutputStream out = new FileOutputStream(new File(filePath))) {
                        out.write(plist.getBytes());
                        out.close();
                        LCLogger.info().withMessageKey("publishApp").withMessage("plist文件更新完毕 => " + plist).flush();
                    }
                }
            }
        } else {
            throw new BasicServiceException("版本发布失败，应用plist文件不存在，请确认所属应用是否已经发布！");
        }
    }
}
